package com.wobito.common.interceptor;


import com.wobito.common.constants.BusinessException;
import com.wobito.common.constants.ErrorCode;
import com.wobito.common.utils.IpUtils;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.annotation.PreDestroy;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @Author: lambyang
 * @CreateTime: 2024-09-19
 * @Description:
 * @Version: 1.0
 */
@Component
public class AntiBrushInterceptor implements HandlerInterceptor {
    //IP地址及请求计数器
    private final ConcurrentHashMap<String, AtomicInteger> ipCountMap = new ConcurrentHashMap<>();
    //请求限制
    private final int limit = 100;

    @Scheduled(fixedRate = 5000)
    public void clearIpCount() {
        for (Map.Entry<String, AtomicInteger> entry : ipCountMap.entrySet()) {
            if (entry.getValue().get() > 60) {
                ipCountMap.remove(entry.getKey());
            }
        }
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String clientIp = IpUtils.getClientIp(request);
        //检查IP地址是否超出限制
        AtomicInteger count = ipCountMap.get(clientIp) != null ? ipCountMap.get(clientIp) : new AtomicInteger(0);
        if (count.get() > limit) {
            throw new BusinessException(ErrorCode.FORBIDDEN,"请勿频繁操作");
        } else {
            if (ipCountMap.containsKey(clientIp)) {
                count.incrementAndGet();
                ipCountMap.put(clientIp, count);
            } else {
                ipCountMap.put(clientIp, count);
            }
        }
        return true;
    }

    @PreDestroy
    public void destroy() {
        ipCountMap.clear();
    }
}
